package cn.itrip.service.impl;

import cn.itrip.commons.DateUtil;
import cn.itrip.commons.RedisAPI;
import cn.itrip.dao.ItripHotelDao;
import cn.itrip.dao.ItripHotelRoomDao;
import cn.itrip.dao.ItripHotelTempStoreDao;
import cn.itrip.dto.HotelOrderDTO;
import cn.itrip.entity.ItripHotel;
import cn.itrip.entity.ItripHotelOrder;
import cn.itrip.dao.ItripHotelOrderDao;
import cn.itrip.entity.ItripHotelRoom;
import cn.itrip.entity.ItripUser;
import cn.itrip.service.ItripHotelOrderService;
import cn.itrip.vo.PreOrderVO;
import cn.itrip.vo.StoreVO;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 订单表(ItripHotelOrder)表服务实现类
 *
 * @author makejava
 * @since 2022-04-14 22:34:56
 */
@Service("itripHotelOrderService")
public class ItripHotelOrderServiceImpl implements ItripHotelOrderService {
	@Resource
	private ItripHotelOrderDao itripHotelOrderDao;

	@Resource
	private ItripHotelTempStoreDao storeDao;
	@Resource
	private ItripHotelDao itripHotelDao;
	@Resource
	private ItripHotelRoomDao itripHotelRoomDao;

	@Resource
	private RedisAPI redisAPI;

	@Override
	public PreOrderVO getpreorderinfo(Map<String, String> map, String token) {
		//1、需要验证token是否有效
		Assert.notNull(redisAPI.get(token), "登录时间已过期,请重新登录");
		//2、调用存储过程刷新对应日期实时库存
		PreOrderVO preOrderVO = new PreOrderVO()
				.setCheckInDate(DateUtil.parseJsDateWidthZone(map.get("checkInDate")))
				.setCheckOutDate(DateUtil.parseJsDateWidthZone(map.get("checkOutDate")))
				.setCount(Integer.parseInt(map.get("count")))
				.setHotelId(Long.parseLong(map.get("hotelId")))
				.setRoomId(Long.parseLong(map.get("roomId")));
		storeDao.flushStore(preOrderVO);
		//3、计算预订日期内可用的库存数量（当日实时库存数-当日未支付订单预订的房间数之和）
		Integer count = Integer.valueOf(map.get("count"));
		Integer minStroe = 0;
		//TODO 获取 某个时间段 内可以用酒店信息
		List<StoreVO> storeVOS = storeDao.queryRoomStore(preOrderVO);
		if (!StringUtils.isEmpty(storeVOS)) {
			minStroe = storeVOS.get(0).getStore();
		}
		if (count > minStroe) {
			throw new RuntimeException("库存不足");
		}
		ItripHotel itripHotel = itripHotelDao.queryHotelNameAndRoomPrice(preOrderVO.getHotelId(),
				preOrderVO.getRoomId());
		preOrderVO.setStore(minStroe);
		preOrderVO.setPrice(itripHotel.getRoomPrice());
		preOrderVO.setHotelName(itripHotel.getHotelName());
		return preOrderVO;
	}

	/**
	 * 通过ID查询单条数据
	 *
	 * @param id 主键
	 * @return 实例对象
	 */
	@Override
	public ItripHotelOrder queryById(Long id) {
		return this.itripHotelOrderDao.queryById(id);
	}

	/**
	 * 分页查询
	 *
	 * @param itripHotelOrder 筛选条件
	 * @param pageRequest     分页对象
	 * @return 查询结果
	 */
	@Override
	public Page<ItripHotelOrder> queryByPage(ItripHotelOrder itripHotelOrder, PageRequest pageRequest) {
		long total = this.itripHotelOrderDao.count(itripHotelOrder);
		return new PageImpl<>(this.itripHotelOrderDao.queryAllByLimit(itripHotelOrder, pageRequest), pageRequest, total);
	}

	/**
	 * 新增数据
	 *
	 * @param itripHotelOrder 实例对象
	 * @return 实例对象
	 */
	@Override
	public ItripHotelOrder insert(ItripHotelOrder itripHotelOrder) {
		this.itripHotelOrderDao.insert(itripHotelOrder);
		return itripHotelOrder;
	}

	/**
	 * 修改数据
	 *
	 * @param itripHotelOrder 实例对象
	 * @return 实例对象
	 */
	@Override
	public ItripHotelOrder update(ItripHotelOrder itripHotelOrder) {
		this.itripHotelOrderDao.update(itripHotelOrder);
		return this.queryById(itripHotelOrder.getId());
	}

	/**
	 * 通过主键删除数据
	 *
	 * @param id 主键
	 * @return 是否成功
	 */
	@Override
	public boolean deleteById(Long id) {
		return this.itripHotelOrderDao.deleteById(id) > 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ItripHotelOrder itriptxCreateOrderService(HotelOrderDTO hotelOrderDto, String token) throws Exception {
		ItripUser itripUser = JSONObject.parseObject(redisAPI.get(token), ItripUser.class);
		Assert.notNull(itripUser, "请先登录再下单");
		ItripHotelOrder itripHotelOrder = this.HotelOrderDTOConvertDO(hotelOrderDto, itripUser);
		itripHotelOrderDao.insert(itripHotelOrder);
		return itripHotelOrder;
	}

	public ItripHotelOrder HotelOrderDTOConvertDO(HotelOrderDTO hotelOrderDTO, ItripUser itripUser)
			throws ParseException {
		System.out.println("hotelOrderDTO = " + hotelOrderDTO);
		ItripHotelOrder itripHotelOrder = new ItripHotelOrder();
		BeanUtils.copyProperties(hotelOrderDTO, itripHotelOrder);
		//设置用户ID
		itripHotelOrder.setUserId(itripUser.getId());
		itripHotelOrder.setCreatedBy(itripUser.getId());
		//租房的天数
		int day = DateUtil.DaysCount(itripHotelOrder.getCheckInDate()
				, itripHotelOrder.getCheckOutDate());
		itripHotelOrder.setBookingDays(day);
		itripHotelOrder.setBookType(2);
		//同住人姓名
		String linkUserName = hotelOrderDTO.getLinkUser().stream().
				//将linkUser集合，转换成String类型的集合
						map(l -> l.getLinkUserName()).collect(Collectors.joining(","));
		itripHotelOrder.setLinkUserName(linkUserName);
		//租房的总价格
		ItripHotelRoom itripHotelRoom = itripHotelRoomDao.queryById(itripHotelOrder.getRoomId());
		double price = (itripHotelRoom.getRoomPrice() * itripHotelOrder.getCount()) * day;
		itripHotelOrder.setPayAmount(price);
		//订单号
		itripHotelOrder.setOrderNo(UUID.randomUUID().toString().replaceAll("-", ""));
		itripHotelOrder.setOrderStatus(0);
		itripHotelOrder.setCreationDate(new Date());
		System.err.println("itripHotelOrder = " + itripHotelOrder);
		//还有一个字符类型没有设置
		return itripHotelOrder;
	}
}
